/*
* name;
*/
class LevelUILogic extends ui.LevelUI {
    private m_TweenNewTileRoot: Laya.Tween = null;
    private m_newTileStartRotation: number;
    private m_newTileNum1: number;
    private m_newTileNum2: number;
    private m_newTileCount: number;
    private m_seleShowTileIndex1: number = -1;
    private m_seleShowTileIndex2: number = -1;
    private m_TileUILogicList: TileUILogic[] = [];
    private m_bDragNewTile: boolean = false;

    private m_CheckMergeIndexList: number[] = [];
    private m_FindMergeIndexList: number[] = [];
    private m_isDelMode: boolean = false;


    private static LINENUM: number[] = [4, 5, 6, 7, 6, 5, 4];
    private static NEWROOT_CENTERX: number = 8;
    private static NEWROOT_BOTTOM: number = 257;
    private static MAXTILESHOWNUM: number = 7;


    /**
     * Setter $m_isDelMode
     * @param {boolean } value
     */
    public set $m_isDelMode(value: boolean) {
        this.m_isDelMode = value;
    }
    constructor() {
        super();
        this.m_pauseBt.on(Laya.Event.CLICK, this, this.OnClickPause);
        this.m_newTileRoot.on(Laya.Event.MOUSE_DOWN, this, this.StartDragNewTile);
        this.m_newTileRoot.on(Laya.Event.MOUSE_UP, this, this.EndDragNewTile);
        this.m_NewTileBak.on(Laya.Event.CLICK, this, this.CovertNewTile);
        this.m_refresh.on(Laya.Event.CLICK, this, this.CreateNewTile);
        this.m_Del.on(Laya.Event.CLICK, this, () => {
            this.m_isDelMode = !this.m_isDelMode;
        });


        Laya.timer.frameLoop(2, this, () => {
            if (this.m_NewTileBak.rotation > 360) {
                this.m_NewTileBak.rotation = this.m_NewTileBak.rotation - 360;
            }
            this.m_NewTileBak.rotation = this.m_NewTileBak.rotation + 1;
        });
        Laya.timer.frameLoop(1, this, this.CheckShowTileStartDrag);
        this.LoadBakTile();

    }
    public InitUI(): void {
        this.m_bestScore.text = "0";
        this.m_curVaule.text = "0";
        this.m_TileUILogicList.forEach(element => {
            element.HideShowTile();
        });
        this.m_TweenNewTileRoot = null;
        this.m_newTileStartRotation = 0;
        this.m_newTileNum1 = 0;
        this.m_newTileNum2 = 0;
        this.m_newTileCount = 0;
        this.m_seleShowTileIndex1 = -1;
        this.m_seleShowTileIndex2 = -1;
        this.m_bDragNewTile = false;
        this.m_CheckMergeIndexList = [];
        this.m_FindMergeIndexList = [];
        this.m_isDelMode = false;

        this.CreateNewTile();
    }
    private IsMerge(): boolean {
        return this.m_CheckMergeIndexList.length > 0;
    }
    public IsDelMode(): boolean {
        if (this.IsMerge()) {
            return false;
        }
        return this.m_isDelMode;
    }
    private CreateNewTile() {
        if (this.IsMerge()) {
            return;
        }
        this.m_newTileRoot.visible = true;
        let randRotation = [60, 120, 0];
        this.m_newTileNum1 = UtilityTool.RandomNum(1, 6);
        this.m_newTileNum2 = UtilityTool.RandomNum(1, 6);
        this.m_newTileCount = 2;
        let newTile1Path = "LevelUI/" + this.m_newTileNum1 + ".png";
        let newTile2Path = "LevelUI/" + this.m_newTileNum2 + ".png";
        this.m_newTile1.texture = Laya.loader.getRes(newTile1Path);
        this.m_newTile2.texture = Laya.loader.getRes(newTile2Path);
        this.m_newTileStartRotation = randRotation[UtilityTool.RandomNum(0, 2)];
        this.m_newTileRoot.rotation = this.m_newTileStartRotation;
        this.m_newTileRoot.centerX = LevelUILogic.NEWROOT_CENTERX;
        this.m_newTileRoot.bottom = LevelUILogic.NEWROOT_BOTTOM;

    }
    private StartDragNewTile(): void {
        if (this.IsMerge()) {
            return;
        }
        this.StopNewTileRootTween();
        this.m_newTileRoot.startDrag();
        this.m_bDragNewTile = true;
    }
    private EndDragNewTile(): void {
        if (this.IsMerge()) {
            return;
        }
        this.m_bDragNewTile = false;
        this.CheckShowTileEndDrag();
    }
    private CovertNewTile() {
        if (this.m_TweenNewTileRoot) {
            return;
        }
        this.m_newTileStartRotation = this.m_newTileStartRotation + 180;
        this.m_TweenNewTileRoot = Laya.Tween.to(this.m_newTileRoot, { rotation: this.m_newTileStartRotation }, 500, Laya.Ease.linearIn,
            Laya.Handler.create(this, () => { this.m_TweenNewTileRoot = null }));

    }
    private StopNewTileRootTween(): void {
        if (this.m_TweenNewTileRoot) {
            this.m_TweenNewTileRoot.complete();
        }
        // this.m_newTileRoot.rotation = this.m_newTileStartRotation;
    }
    private LoadBakTile() {
        for (let line = 0; line < LevelUILogic.LINENUM.length; line++) {
            for (let i = 0; i < LevelUILogic.LINENUM[line]; i++) {
                let bakTile = new TileUILogic();
                bakTile.HideShowTile();
                bakTile.x = i * 140;
                bakTile.y = 0;
                switch (line + 1) {
                    case 1:
                        this.m_tileLine1.addChild(bakTile);
                        break;
                    case 2:
                        this.m_tileLine2.addChild(bakTile);
                        break;
                    case 3:
                        this.m_tileLine3.addChild(bakTile);
                        break;
                    case 4:
                        this.m_tileLine4.addChild(bakTile);
                        break;
                    case 5:
                        this.m_tileLine5.addChild(bakTile);
                        break;
                    case 6:
                        this.m_tileLine6.addChild(bakTile);
                        break;
                    case 7:
                        this.m_tileLine7.addChild(bakTile);
                        break;
                }
                this.m_TileUILogicList.push(bakTile);
            }
        };
        this.m_tileLine1.centerX = 0;
        this.m_tileLine2.centerX = 0;
        this.m_tileLine3.centerX = 0;
        this.m_tileLine4.centerX = 0;
        this.m_tileLine5.centerX = 0;
        this.m_tileLine6.centerX = 0;
        this.m_tileLine7.centerX = 0;

    }
    private OnClickPause(): void {
        GameManager.Instance.ShowMainUI();
    }

    private CheckShowTileStartDrag(): void {
        if (this.m_bDragNewTile == false) {
            return;
        }
        this.m_seleShowTileIndex1 = -1;
        this.m_seleShowTileIndex2 = -1;
        for (let checkIndex = 0; checkIndex < this.m_TileUILogicList.length; checkIndex++) {
            let tilelogic = this.m_TileUILogicList[checkIndex];
            if (tilelogic.$m_IsHaveShowTile == false) {
                let posTile: laya.maths.Point = tilelogic.m_bakTile.localToGlobal(new Laya.Point(tilelogic.m_bakTile.width / 2, tilelogic.m_bakTile.height / 2));
                let bSele: boolean = false;
                if (this.m_newTile1.visible) {
                    let posNewTile: laya.maths.Point = this.m_newTile1.localToGlobal(new Laya.Point(this.m_newTile1.width / 2, this.m_newTile1.height / 2));
                    let dis = posTile.distance(posNewTile.x, posNewTile.y);
                    if (dis < 20) {
                        tilelogic.SetShowTile(this.m_newTileNum1, true);
                        this.m_seleShowTileIndex1 = checkIndex;
                        bSele = true;
                    }
                }
                if (this.m_newTile2.visible) {
                    let posNewTile: laya.maths.Point = this.m_newTile2.localToGlobal(new Laya.Point(this.m_newTile2.width / 2, this.m_newTile2.height / 2));
                    let dis = posTile.distance(posNewTile.x, posNewTile.y);
                    if (dis < 20) {
                        tilelogic.SetShowTile(this.m_newTileNum2, true);
                        this.m_seleShowTileIndex2 = checkIndex;
                        bSele = true;
                    }
                }
                if (bSele == false) {
                    tilelogic.HideShowTile();
                }
            }
        }
    }

    private CheckShowTileEndDrag(): void {
        if (this.m_CheckMergeIndexList.length > 0) {
            return;
        }
        let isCanShow: boolean = false;
        if (this.m_seleShowTileIndex1 >= 0 && this.m_seleShowTileIndex1 < this.m_TileUILogicList.length) {
            this.m_TileUILogicList[this.m_seleShowTileIndex1].HideShowTile();
        }
        if (this.m_seleShowTileIndex2 >= 0 && this.m_seleShowTileIndex2 < this.m_TileUILogicList.length) {
            this.m_TileUILogicList[this.m_seleShowTileIndex2].HideShowTile();
        }
        if (this.m_newTile1.visible &&
            this.m_newTile2.visible &&
            this.m_seleShowTileIndex1 >= 0 &&
            this.m_seleShowTileIndex1 < this.m_TileUILogicList.length &&
            this.m_seleShowTileIndex2 >= 0 &&
            this.m_seleShowTileIndex2 < this.m_TileUILogicList.length
        ) {
            this.m_TileUILogicList[this.m_seleShowTileIndex1].SetShowTile(this.m_newTileNum1, false);
            this.m_TileUILogicList[this.m_seleShowTileIndex2].SetShowTile(this.m_newTileNum2, false);
            isCanShow = true;
            if (this.m_newTileNum1 == this.m_newTileNum2) {
                this.m_CheckMergeIndexList.push(this.m_seleShowTileIndex1);
            }
            else {
                this.m_CheckMergeIndexList.push(this.m_seleShowTileIndex1);
                this.m_CheckMergeIndexList.push(this.m_seleShowTileIndex2);
            }

        }
        else if (this.m_newTile1.visible &&
            this.m_newTile2.visible == false &&
            this.m_seleShowTileIndex1 >= 0 &&
            this.m_seleShowTileIndex1 < this.m_TileUILogicList.length
        ) {
            this.m_TileUILogicList[this.m_seleShowTileIndex1].SetShowTile(this.m_newTileNum1, false);
            isCanShow = true;
            this.m_CheckMergeIndexList.push(this.m_seleShowTileIndex2);
        }
        this.m_seleShowTileIndex1 = -1;
        this.m_seleShowTileIndex2 = -1;
        if (isCanShow) {
            this.m_newTileRoot.visible = false;
            this.CheckCanMerge();
        }
        else {
            this.StopNewTileRootTween();
            this.m_newTileRoot.rotation = this.m_newTileStartRotation;
            this.m_TweenNewTileRoot = Laya.Tween.to(this.m_newTileRoot, { centerX: LevelUILogic.NEWROOT_CENTERX, bottom: LevelUILogic.NEWROOT_BOTTOM }, 500, Laya.Ease.linearIn,
                Laya.Handler.create(this, () => { this.m_TweenNewTileRoot = null }));
        }

    }
    private CheckCanMerge(): void {
        if (this.m_CheckMergeIndexList.length <= 0) {
            this.CreateNewTile();
            return;
        }
        let checkIndex = this.m_CheckMergeIndexList.pop();
        if (this.m_TileUILogicList[checkIndex].$m_ShowNum < LevelUILogic.MAXTILESHOWNUM) {
            this.m_FindMergeIndexList = [];
            this.m_FindMergeIndexList.push(checkIndex);
            this.FindSameNumNear(checkIndex, this.m_TileUILogicList[checkIndex].$m_ShowNum);
            if (this.m_FindMergeIndexList.length >= 3) {
                this.m_TileUILogicList[checkIndex].SetShowTile(this.m_TileUILogicList[checkIndex].$m_ShowNum + 1, false);
                this.m_CheckMergeIndexList.push(checkIndex);
                this.m_FindMergeIndexList.forEach(element => {
                    if (element != checkIndex) {
                        this.m_TileUILogicList[element].HideShowTile();
                    }
                });
            }
        }

        this.CheckCanMerge();
    }
    private FindSameNumNear(checkIndex: number, checkNum: number): void {

        if (checkIndex >= 0 &&
            checkIndex < this.m_TileUILogicList.length &&
            this.m_TileUILogicList[checkIndex].$m_IsHaveShowTile &&
            this.m_TileUILogicList[checkIndex].$m_ShowNum == checkNum) {

            for (let nearIndex = 0; nearIndex < 6; nearIndex++) {
                let findNearIndex = this.GetNearIndexByType(checkIndex, nearIndex);
                if (findNearIndex != -1 &&
                    this.m_TileUILogicList[findNearIndex].$m_IsHaveShowTile &&
                    this.m_TileUILogicList[findNearIndex].$m_ShowNum == checkNum) {
                    let havasameIndex = false;
                    this.m_FindMergeIndexList.forEach(element => {
                        if (element == findNearIndex) {
                            havasameIndex = true;
                        }
                    });
                    if (havasameIndex) {
                        continue;
                    }
                    this.m_FindMergeIndexList.push(findNearIndex);
                    this.FindSameNumNear(findNearIndex, checkNum);
                }
            }
        }

    }
    private GetNearIndexByType(findIndex: number, findType: number): number {
        let lineNumSelf = this.GetLineNumByIndex(findIndex);
        if (lineNumSelf >= 0 && lineNumSelf < LevelUILogic.LINENUM.length) {
            switch (findType) {
                case 0: //左边的
                    {
                        let nearIndex = findIndex - 1;
                        let lineNumNear = this.GetLineNumByIndex(nearIndex);
                        if (lineNumNear != -1 && lineNumSelf == lineNumNear) {
                            return nearIndex;
                        }
                        break;
                    }
                case 1: //右边的
                    {
                        let nearIndex = findIndex + 1;
                        let lineNumNear = this.GetLineNumByIndex(nearIndex);
                        if (lineNumNear != -1 && lineNumSelf == lineNumNear) {
                            return nearIndex;
                        }
                        break;
                    }
                case 2: //上一行左边的
                    {
                        let nearIndex = -1;
                        if (lineNumSelf < Math.ceil(LevelUILogic.LINENUM.length / 2)) {
                            nearIndex = findIndex - LevelUILogic.LINENUM[lineNumSelf];
                        }
                        else {
                            nearIndex = findIndex - LevelUILogic.LINENUM[lineNumSelf] - 1;
                        }
                        let lineNumNear = this.GetLineNumByIndex(nearIndex);
                        if (lineNumNear != -1 && lineNumSelf == lineNumNear + 1) {
                            return nearIndex;
                        }
                        break;
                    }
                case 3: //上一行右边的
                    {
                        let nearIndex = -1;
                        if (lineNumSelf < Math.ceil(LevelUILogic.LINENUM.length / 2)) {
                            nearIndex = findIndex - LevelUILogic.LINENUM[lineNumSelf] + 1;
                        }
                        else {
                            nearIndex = findIndex - LevelUILogic.LINENUM[lineNumSelf];
                        }
                        let lineNumNear = this.GetLineNumByIndex(nearIndex);
                        if (lineNumNear != -1 && lineNumSelf == lineNumNear + 1) {
                            return nearIndex;
                        }
                        break;
                    }
                case 4: //下一行左边的
                    {
                        let nearIndex = -1;
                        if (lineNumSelf < Math.floor(LevelUILogic.LINENUM.length / 2)) {
                            nearIndex = findIndex + LevelUILogic.LINENUM[lineNumSelf];
                        }
                        else {
                            nearIndex = findIndex + LevelUILogic.LINENUM[lineNumSelf] - 1;
                        }
                        let lineNumNear = this.GetLineNumByIndex(nearIndex);
                        if (lineNumNear != -1 && lineNumSelf == lineNumNear - 1) {
                            return nearIndex;
                        }
                        break;
                    }
                case 5: //下一行右边的
                    {
                        let nearIndex = -1;
                        if (lineNumSelf < Math.floor(LevelUILogic.LINENUM.length / 2)) {
                            nearIndex = findIndex + LevelUILogic.LINENUM[lineNumSelf] + 1;
                        }
                        else {
                            nearIndex = findIndex + LevelUILogic.LINENUM[lineNumSelf];
                        }
                        let lineNumNear = this.GetLineNumByIndex(nearIndex);
                        if (lineNumNear != -1 && lineNumSelf == lineNumNear - 1) {
                            return nearIndex;
                        }
                        break;
                    }

            }
        }


        return -1;
    }
    private GetLineNumByIndex(checkIndex: number): number {
        let startIndex = 0;
        for (let i = 0; i < LevelUILogic.LINENUM.length; i++) {
            let endIndex = startIndex + LevelUILogic.LINENUM[i];
            if (checkIndex >= startIndex && checkIndex < endIndex) {
                return i;
            }
            startIndex = endIndex;
        }
        return -1;
    }
}